package com.cancer.common.util;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;

public final class JSONUtil {
	private static ObjectMapper mapper;
	
	static {
		mapper = new ObjectMapper();
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略json和bean的字段数量不匹配
		mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // 
//		mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); //解决json中存在转移字符Illegal unquoted character 
	}

	/**
	 * 以yyyy-MM-dd hh:mm:ss去格式化日期
	 * 2016-11-07 19:30:20
	 * 
	 * @company GeekPlus
	 * @project beetle
	 * @author 刘俊
	 * @date 2016年11月24日
	 * @since 1.0.0
	 */
	public static class DateTimeSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String formattedDate = formatter.format(value);
            jgen.writeString(formattedDate);
        }
	}
	
	/**
	 * 以yyyy-MM-dd去格式化日期
	 * 2016-11-07
	 * 
	 * @company GeekPlus
	 * @project beetle
	 * @author 刘俊
	 * @date 2016年11月24日
	 * @since 1.0.0
	 */
	public static class DateSerializer extends JsonSerializer<Date> {
		@Override
		public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
			String formattedDate = formatter.format(value);
			jgen.writeString(formattedDate);
		}
	}
	
	public static ObjectMapper getMapper() {

		return mapper;
	}
	
	/**
	 * 将json转成指定类型在java bean
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param json	json字串
	 * @param clz	java类型
	 * @return
	 */
	public static <T> T jsonToObj(String json, Class<T> clz) {
		try {
			return mapper.readValue(json, clz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将json转成指定类型在java bean(可完成更复杂的类型转换)
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param json	json字串
	 * @param type	TypeReference转换类型
	 * @return
	 */
	public static <T> T jsonToObj(String json, TypeReference<T> type) {
		try {
			return mapper.readValue(json, type);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将json串中指定某个属性转换成java bean
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param json		json字串
	 * @param propName	属性名
	 * @param clz		java类型
	 * @return
	 */
	public static <T> T jsonToObj(String json, String propName, Class<T> clz) {
		try {
			JsonNode node = mapper.readTree(json).path(propName);
			
			return mapper.readValue(node.toString(), clz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将json串中指定某个属性转换成java bean(可完成更复杂的类型转换)
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param json		json字串
	 * @param propName	属性名
	 * @param type		TypeReference转换类型
	 * @return
	 */
	public static <T> T jsonToObj(String json, String propName, TypeReference<T> type) {
		try {
			JsonNode node = mapper.readTree(json).path(propName);
			
			return mapper.readValue(node.toString(), type);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * json转成Map
	 */
	public static Map<String, Object> jsonToMap(String json) {
		Map<String, Object> map = null;
		
		try {
			map = mapper.readValue(json, new TypeReference<HashMap<String, Object>>() {});
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return map;
	}
	
	/**
	 * 将json字串转换成jsonNode
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param json	json字串
	 * @return
	 */
	public static JsonNode jsonToNode(String json) {
		try {
			return mapper.readTree(json);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将jsonNode转换成java bean
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param node	json节点
	 * @param clz	java类型
	 * @return
	 */
	public static <T> T nodeToObj(JsonNode node, Class<T> clz) {
		try {
			return mapper.readValue(node.toString(), clz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将jsonNode转换成java bean(可完成更复杂的类型转换)
	 * 
	 * @author 刘俊 2015年10月15日
	 * @param node	json节点
	 * @param type	TypeReference转换类型
	 * @return
	 */
	public static <T> T nodeToObj(JsonNode node, TypeReference<T> type) {
		try {
			return mapper.readValue(node.toString(), type);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 将对象转为json字串
	 */
	public static String objToJson(Object obj) {
		try {
			return mapper.writeValueAsString(obj);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
}
